#include <OutputStreamMethod.h>

template <typename Unit>
Measurement<Unit>::Measurement(unsigned int amount, const Unit* unit)
    : amountInBase(amount * unit->toBase())
    , amount(amount)
    , unit(unit)
{
}

template <typename Unit>
Measurement<Unit>::Measurement(unsigned int amountInBase)
    : amountInBase(amountInBase)
{
}

template <typename Unit>
bool Measurement<Unit>::operator == (const Measurement<Unit>& second) const
{
    return this->amountInBase == second.amountInBase;
}

template <typename Unit>
bool Measurement<Unit>::operator != (const Measurement<Unit>& second) const
{
    return !(*this == second);
}

template <typename Unit>
Measurement<Unit> Measurement<Unit>::operator + (const Measurement<Unit>& second) const
{
	return Measurement(this->amountInBase + second.amountInBase);
}

template <typename Unit>
Measurement<Unit> Measurement<Unit>::operator / (const Measurement<Unit>& second) const
{
    return Measurement(amountInBase / second.amountInBase, second.unit);
}

template <typename Unit>
Measurement<Unit> Measurement<Unit>::operator % (const Measurement<Unit>& second) const
{
    return Measurement(amountInBase % second.amountInBase, unit);
}

template <typename Unit>
void Measurement<Unit>::outputStream(const OutputStreamMethod& outputMethod, std::ostringstream& os)
{
    outputMethod.output(amountInBase, unit, os);
}

template <typename Unit>
std::ostringstream& operator << (std::ostringstream& os, const Measurement<Unit>& measurement)
{
    if (measurement.amount != 0) os << measurement.amount << " " << measurement.unit->toString();
    return os;
}

template <typename Unit>
bool Measurement<Unit>::empty()
{
    return amountInBase == 0;
}

